import threading
import time
import regutil
import util
from multiprocessing import Queue
import AhoEdgeRegisterService_pb2 as ae
import AhoEdgeRegisterService_pb2_grpc as aeg
import grpc


print("解析DNS reg.sdju.ahhhh.com.cn ")
address = regutil.get_reg_address()
print(f"解析结果： {address}")
register_server = (address, 50051)
local_address = util.get_local_address()
print(f"获取的本地地址是：{local_address}")

class AhoEdgeClient(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
        self.in_que = Queue(1)
        self.out_que = Queue(1)
        print(f"connecting to register server: {register_server}")
        self.channel = grpc.insecure_channel(f"{register_server[0]}:{register_server[1]}")
        

    
    def get_pip(self):
        return (self.in_que, self.out_que)

    def run(self) -> None:
        self.stub = aeg.RegisterServiceStub(self.channel)
        while True:
            try:
                respone = self.stub.registerUser(ae.UserInfo(id=1, ipAddress=local_address, port=1010))
                print(f"\nsuccess connected to {register_server}")
                break
            except grpc.RpcError as _:
                time.sleep(2.0)
        self.user_id = respone.user_id
        print(f"user_id = {self.user_id}")
        print("standby...")
        while True:
            cmd = self.in_que.get()
            if cmd == 0x0:
                print("\ngot command. gRPC:getService calling")
                try:
                    response = self.stub.getService(ae.QueryRequest(serviceName="avoid"))
                except Exception as e:
                    print("\nerror in gRPC")
                    return
                print("\ngot gRPC response. write to out_que")
                self.out_que.put((response.ipAddress, response.port, response.id))
            elif cmd < 0xA:
                print(f"\nreport connected to {cmd} service")
                self.stub.reportConnected(ae.ConnectedMessage(user_id=self.user_id, service_id=int(cmd)))
            elif cmd == 0xA:
                print("\nrevc quit signal")
                self.stub.unregisterUser(ae.UserInfo(id=self.user_id))
                self.channel.close()
                return
            elif cmd > 0xE:
                server_id = cmd - 0xE
                print("\nreportServiceStatus")
                self.stub.reportServiceStatus(ae.ServiceStatusInfo(status=ae.ServiceStatusInfo.Status.ERROR,named="avoid", serverId=server_id))

aho_edge_client_thread = AhoEdgeClient()

(send, recv) = aho_edge_client_thread.get_pip()
aho_edge_client_thread.start()

try:
    while (cmd := input(">")):
        if cmd == 'query':
            send.put(0x0)
            (ip, port, service_id) = recv.get()
            if ip != '0.0.0.0':
                print(f"\ngot server {ip}:{port}")
                ack = input("Did you wanna to connect?(Yes/no)\n>")
                if ack.lower() == 'yes':
                    send.put(service_id)
                else:
                    print("\nfine.")
            else:
                print("\nNot more server now")
        elif cmd == 'q':
            send.put(0xA)
            break
        elif cmd == 're':
            server_id = input("\ntype the error service id:\n>")
            send.put(0xE+int(server_id))
except Exception as _:
    send.put(0xA)